//
//  WCAppController.m
//  WabbitCode
//
//  Created by William Towe on 1/21/09.
//  Copyright 2009 Revolution Software. All rights reserved.
//

#import "WCAppController.h"
#import "WCMacros.h"
#import "WCPreferencesWindowController.h"
#import "NSArray+WCExtensions.h"
#import "WCGroup.h"
#import "WCBuildTarget.h"
#import "WCProject.h"
#import "EncodingManager.h"


NSString *kWCPrefsGeneralWhenApplicationLaunchesKey = @"kWCPrefsGeneralWhenApplicationLaunchesKey";

NSString *kWCPrefsAppearanceConsoleFontKey = @"kWCPrefsAppearanceConsoleFontKey";

NSString *kWCPrefsBuildingPlaceBuildProductsInKey = @"kWCPrefsBuildingPlaceBuildProductsInKey";
NSString *kWCPrefsBuildingProductsCustomDirectoryKey = @"kWCPrefsBuildingProductsCustomDirectoryKey";
NSString *kWCPrefsBuildingBuildResultsWindowOpenDuringBuilds = @"kWCPrefsBuildingBuildResultsWindowOpenDuringBuilds";
NSString *kWCPrefsBuildingBuildResultsWindowCloseAfterBuilds = @"kWCPrefsBuildingBuildResultsWindowCloseAfterBuilds";
NSString *kWCPrefsBuildingErrorsAndWarningsGroupOpenDuringBuildsKey = @"kWCPrefsBuildingErrorsAndWarningsGroupOpenDuringBuildsKey";
NSString *kWCPrefsBuildingErrorsAndWarningsGroupCloseAfterBuildsKey = @"kWCPrefsBuildingErrorsAndWarningsGroupCloseAfterBuildsKey";
NSString *kWCPrefsBuildingForUnsavedFilesKey = @"kWCPrefsBuildingForUnsavedFilesKey";
NSString *kWCPrefsBuildingDisplayErrorAndWarningInTheDockKey = @"kWCPrefsBuildingDisplayErrorAndWarningInTheDockKey";

NSString *kWCPrefsEditorDefaultShowInvisibleCharactersKey = @"kWCPrefsEditorDefaultShowInvisibleCharactersKey";
NSString *kWCPrefsEditorDefaultWrapLinesKey = @"kWCPrefsEditorDefaultWrapLinesKey";
NSString *kWCPrefsEditorDefaultAutomaticallyIndentNewLinesKey = @"kWCPrefsEditorDefaultAutomaticallyIndentNewLinesKey";
NSString *kWCPrefsEditorSelectedTabViewIdentifierKey = @"kWCPrefsEditorSelectedTabViewIdentifierKey";
NSString *kWCPrefsEditorDefaultFileEncodingKey = @"kWCPrefsEditorDefaultFileEncodingKey";
NSString *kWCPrefsEditorDefaultShowGutterKey = @"kWCPrefsEditorDefaultShowGutterKey";
NSString *kWCPrefsEditorDefaultShowLineNumbersKey = @"kWCPrefsEditorDefaultShowLineNumbersKey";
NSString *kWCPrefsEditorDefaultShowErrorsKey = @"kWCPrefsEditorDefaultShowErrorsKey";
NSString *kWCPrefsEditorDefaultShowWarningsKey = @"kWCPrefsEditorDefaultShowWarningsKey";
NSString *kWCPrefsEditorDefaultAutomaticallyInsertAClosingParenthesisKey = @"kWCPrefsEditorDefaultAutomaticallyInsertAClosingParenthesisKey";

NSString *kWCPrefsEditorTabWidthKey = @"kWCPrefsEditorTabWidthKey";

NSString *kWCPrefsEditorGotoLineOrCharacter = @"kWCPrefsEditorGotoLineOrCharacter";
NSString *kWCPrefsEditorFontKey = @"kWCPrefsEditorFontKey";
NSString *kWCPrefsEditorTextColorKey = @"kWCPrefsEditorTextColorKey";
NSString *kWCPrefsEditorBackgroundColorKey = @"kWCPrefsEditorBackgroundColorKey";
NSString *kWCPrefsEditorInvisibleCharacterColorKey = @"kWCPrefsEditorInvisibleCharacterColorKey";

NSString *kWCPrefsEditorLineHighlightEnabledKey = @"kWCPrefsEditorLineHighlightEnabledKey";
NSString *kWCPrefsEditorLineHighlightColorKey = @"kWCPrefsEditorLineHighlightColorKey";
NSString *kWCPrefsEditorSyntaxHighlightingEnabledKey = @"kWCPrefsEditorSyntaxHighlightingEnabledKey";
NSString *kWCPrefsEditorDirectivesEnabledKey = @"kWCPrefsEditorDirectivesEnabledKey";
NSString *kWCPrefsEditorDirectivesColorKey = @"kWCPrefsEditorDirectivesColorKey";
NSString *kWCPrefsEditorConditionalRegistersEnabledKey = @"kWCPrefsEditorConditionalRegistersEnabledKey";
NSString *kWCPrefsEditorConditionalRegistersColorKey = @"kWCPrefsEditorConditionalRegistersColorKey";
NSString *kWCPrefsEditorOperationalCodesEnabledKey = @"kWCPrefsEditorOperationalCodesEnabledKey";
NSString *kWCPrefsEditorOperationalCodesColorKey = @"kWCPrefsEditorOperationalCodesColorKey";
NSString *kWCPrefsEditorOtherRegistersEnabledKey = @"kWCPrefsEditorOtherRegistersEnabledKey";
NSString *kWCPrefsEditorOtherRegistersColorKey = @"kWCPrefsEditorOtherRegistersColorKey";
NSString *kWCPrefsEditorLabelsEnabledKey = @"kWCPrefsEditorLabelsEnabledKey";
NSString *kWCPrefsEditorLabelsColorKey = @"kWCPrefsEditorLabelsColorKey";
NSString *kWCPrefsEditorEquatesEnabledKey = @"kWCPrefsEditorEquatesEnabledKey";
NSString *kWCPrefsEditorEquatesColorKey = @"kWCPrefsEditorEquatesColorKey";
NSString *kWCPrefsEditorPreProcessorCommandsEnabledKey = @"kWCPrefsEditorPreProcessorCommandsEnabledKey";
NSString *kWCPrefsEditorPreProcessorCommandsColorKey = @"kWCPrefsEditorPreProcessorCommandsColorKey";
NSString *kWCPrefsEditorStringsEnabledKey = @"kWCPrefsEditorStringsEnabledKey";
NSString *kWCPrefsEditorStringsColorKey = @"kWCPrefsEditorStringsColorKey";
NSString *kWCPrefsEditorBaseTenNumbersEnabledKey = @"kWCPrefsEditorBaseTenNumbersEnabledKey";
NSString *kWCPrefsEditorBaseTenNumbersColorKey = @"kWCPrefsEditorBaseTenNumbersColorKey";
NSString *kWCPrefsEditorBaseSixteenNumbersEnabledKey = @"kWCPrefsEditorBaseSixteenNumbersEnabledKey";
NSString *kWCPrefsEditorBaseSixteenNumbersColorKey = @"kWCPrefsEditorBaseSixteenNumbersColorKey";
NSString *kWCPrefsEditorBaseTwoNumbersEnabledKey = @"kWCPrefsEditorBaseTwoNumbersEnabledKey";
NSString *kWCPrefsEditorBaseTwoNumbersColorKey = @"kWCPrefsEditorBaseTwoNumbersColorKey";
NSString *kWCPrefsEditorCommentsEnabledKey = @"kWCPrefsEditorCommentsEnabledKey";
NSString *kWCPrefsEditorCommentsColorKey = @"kWCPrefsEditorCommentsColorKey";

NSString *kWCPrefsFilesCheckIfFilesHaveBeenUpdatedByAnotherApplicationKey = @"kWCPrefsFilesCheckIfFilesHaveBeenUpdatedByAnotherApplicationKey";
NSString *kWCPrefsFilesAutomaticallyUpdateChangedFilesKey = @"kWCPrefsFilesAutomaticallyUpdateChangedFilesKey";

NSString *kWCPrefsTabsAnimateAddingAndRemovingKey = @"kWCPrefsTabsAnimateAddingAndRemovingKey";
NSString *kWCPrefsTabsAllowScrubbingOfTabsKey = @"kWCPrefsTabsAllowScrubbingOfTabsKey";
NSString *kWCPrefsTabsOpenNewTabsInBackgroundKey = @"kWCPrefsTabsOpenNewTabsInBackgroundKey";

NSString *kWCPrefsAddToProjectCopyFilesKey = @"kWCPrefsAddToProjectCopyFilesKey";
NSString *kWCPrefsAddToProjectTextEncodingKey = @"kWCPrefsAddToProjectTextEncodingKey";
NSString *kWCPrefsAddToProjectOpenFilesAfterAddKey = @"kWCPrefsAddToProjectOpenFilesAfterAddKey";

NSString *kWCPrefsNewFileOpenNewFileAfterCreationKey = @"kWCPrefsNewFileOpenNewFileAfterCreationKey";

NSString *kWCPrefsNewTargetMakeNewTargetActiveKey = @"kWCPrefsNewTargetMakeNewTargetActiveKey";
NSString *kWCPrefsNewTargetCopyActiveTargetsBuildStepsToNewTargetKey = @"kWCPrefsNewTargetCopyActiveTargetsBuildStepsToNewTargetKey";

NSString *kWCPrefsNewConfigurationCopyActiveConfigurationsDefinesToNewConfigurationKey = @"kWCPrefsNewConfigurationCopyActiveConfigurationsDefinesToNewConfigurationKey";
NSString *kWCPrefsNewConfigurationCopyActiveConfigurationsIncludeDirectoriesToNewConfigurationKey = @"kWCPrefsNewConfigurationCopyActiveConfigurationsIncludeDirectoriesToNewConfigurationKey";

NSString *kWCPrefsNewIncludeDirectoryRecursivelyAddSubdirectoriesKey = @"kWCPrefsNewIncludeDirectoryRecursivelyAddSubdirectoriesKey";

NSString *kWCNewProjectFromFolderRootFolderKey = @"kWCNewProjectFromFolderRootFolderKey";
NSString *kWCNewProjectFromFolderTargetModelKey = @"kWCNewProjectFromFolderTargetModelKey";
NSString *kWCNewProjectFromFolderTargetOutputTypeKey = @"kWCNewProjectFromFolderTargetOutputTypeKey";

NSString *kWCProjectUTI = @"org.revsoft.wabbitcode.project";
NSString *kWCAssemblyUTI = @"org.revsoft.wabbitcode.assembly";
NSString *kWCIncludeUTI = @"org.revsoft.wabbitcode.include";

NSString *kWCProjectDataFileName = @"project";
NSString *kWCProjectDataFileExtension = @"wcodedata";
NSString *kWCProjectPreferencesFileExtension = @"wcodeprefs";
NSString *kWCProjectFileExtension = @"wcodeproj";

NSStringEncoding kWCDefaultFileEncoding = NSUTF8StringEncoding;

NSSet *kWCDocumentFileExtensions = nil;

static NSFileManager *fm = nil;

@implementation WCAppController
+ (void)initialize {
	fm = [NSFileManager defaultManager];
	
	kWCDocumentFileExtensions = [[NSSet alloc] initWithObjects:@"asm",@"ASM",@"z80",@"Z80",@"inc",@"INC",nil];
	
	NSMutableDictionary *prefs = [NSMutableDictionary dictionary];
	
	// default startup action
	[prefs setObject:NSNumberWithUnsignedInteger(WCPGWhenApplicationLaunchesShowNewProjectWindow) forKey:kWCPrefsGeneralWhenApplicationLaunchesKey];
	
	// console output font
	[prefs setObject:NSKeyedArchivedObject([NSFont boldSystemFontOfSize:11.0]) forKey:kWCPrefsAppearanceConsoleFontKey];
	
	// place build products in
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBPlaceBuildProductsInProjectDirectory) forKey:kWCPrefsBuildingPlaceBuildProductsInKey];
	// default custom build directory
	[prefs setObject:NSHomeDirectory() forKey:kWCPrefsBuildingProductsCustomDirectoryKey];
	// open build results window during builds
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBBuildResultsWindowOpenDuringBuildsAlways) forKey:kWCPrefsBuildingBuildResultsWindowOpenDuringBuilds];
	// close build results window after builds
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBBuildResultsWindowCloseAfterBuildsNever) forKey:kWCPrefsBuildingBuildResultsWindowCloseAfterBuilds];
	// open errors and warnings group during build
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBErrorsAndWarningsGroupOpenDuringBuildsNever) forKey:kWCPrefsBuildingErrorsAndWarningsGroupOpenDuringBuildsKey];
	// close errors and warnings group after build
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBErrorsAndWarningsGroupCloseAfterBuildsNever) forKey:kWCPrefsBuildingErrorsAndWarningsGroupCloseAfterBuildsKey];
	// for unsaved files
	[prefs setObject:NSNumberWithUnsignedInteger(WCPBForUnsavedFilesAskBeforeBuilding) forKey:kWCPrefsBuildingForUnsavedFilesKey];
	// display error and warning count in the dock
	[prefs setObject:NSNumberTrue forKey:kWCPrefsBuildingDisplayErrorAndWarningInTheDockKey];
	
	// wrap lines in the editor
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultWrapLinesKey];
	// default file encoding
	[prefs setObject:NSNumberWithUnsignedInteger(NoStringEncoding) forKey:kWCPrefsEditorDefaultFileEncodingKey];
	// default show invisible characters
	[prefs setObject:NSNumberFalse forKey:kWCPrefsEditorDefaultShowInvisibleCharactersKey];
	// default show gutter
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultShowGutterKey];
	// default show line numbers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultShowLineNumbersKey];
	// default show errors
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultShowErrorsKey];
	// default show warnings
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultShowWarningsKey];
	// default automatically indent new lines
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultAutomaticallyIndentNewLinesKey];
	// default automatically insert closing parenthesis
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDefaultAutomaticallyInsertAClosingParenthesisKey];
	
	// tab width
	[prefs setObject:NSNumberWithUnsignedInteger(4) forKey:kWCPrefsEditorTabWidthKey];
	
	// goto line or character
	[prefs setObject:NSNumberWithUnsignedInteger(WCPEGotoLineOrCharacterGotoLine) forKey:kWCPrefsEditorGotoLineOrCharacter];
	// editor font
	[prefs setObject:NSKeyedArchivedObject([NSFont userFixedPitchFontOfSize:10.0]) forKey:kWCPrefsEditorFontKey];
	// editor text color
	[prefs setObject:NSKeyedArchivedObject([NSColor textColor]) forKey:kWCPrefsEditorTextColorKey];
	// editor invisible character color
	[prefs setObject:NSKeyedArchivedObject([NSColor darkGrayColor]) forKey:kWCPrefsEditorInvisibleCharacterColorKey];
	// editor background color
	[prefs setObject:NSKeyedArchivedObject([NSColor controlBackgroundColor]) forKey:kWCPrefsEditorBackgroundColorKey];
	// editor line highlight enabled
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorLineHighlightEnabledKey];
	// editor line highlight color
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedWhite:235.0/255.0 alpha:1.0]) forKey:kWCPrefsEditorLineHighlightColorKey];
	// enable syntax highlighting
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorSyntaxHighlightingEnabledKey];
	// coloring of assembler directives
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorDirectivesEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor orangeColor]) forKey:kWCPrefsEditorDirectivesColorKey];
	// coloring of conditional registers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorConditionalRegistersEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedRed:0.0 green:1.0 blue:1.0 alpha:1.0]) forKey:kWCPrefsEditorConditionalRegistersColorKey];
	// coloring of operational codes
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorOperationalCodesEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor blueColor]) forKey:kWCPrefsEditorOperationalCodesColorKey];
	// coloring of remaining registers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorOtherRegistersEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor redColor]) forKey:kWCPrefsEditorOtherRegistersColorKey];
	// coloring of labels
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorLabelsEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedRed:128.0/255.0 green:128.0/255.0 blue:0.0 alpha:1.0]) forKey:kWCPrefsEditorLabelsColorKey];
	// coloring of equates
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorEquatesEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedRed:0.0 green:0.5 blue:0.5 alpha:1.0]) forKey:kWCPrefsEditorEquatesColorKey];
	// coloring of pre processor commands
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorPreProcessorCommandsEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor brownColor]) forKey:kWCPrefsEditorPreProcessorCommandsColorKey];
	// coloring of strings
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorStringsEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor purpleColor]) forKey:kWCPrefsEditorStringsColorKey];
	// coloring of base ten numbers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorBaseTenNumbersEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor blueColor]) forKey:kWCPrefsEditorBaseTenNumbersColorKey];
	// coloring of hexadeciaml numbers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorBaseSixteenNumbersEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor magentaColor]) forKey:kWCPrefsEditorBaseSixteenNumbersColorKey];
	// coloring of binary numbers
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorBaseTwoNumbersEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedRed:0.0 green:128.0/255.0 blue:1.0 alpha:1.0]) forKey:kWCPrefsEditorBaseTwoNumbersColorKey];
	// coloring of single line comments
	[prefs setObject:NSNumberTrue forKey:kWCPrefsEditorCommentsEnabledKey];
	[prefs setObject:NSKeyedArchivedObject([NSColor colorWithCalibratedRed:0.0 green:128.0/255.0 blue:0.0 alpha:1.0]) forKey:kWCPrefsEditorCommentsColorKey];
	
	// check if files have been updated by another application
	[prefs setObject:NSNumberTrue forKey:kWCPrefsFilesCheckIfFilesHaveBeenUpdatedByAnotherApplicationKey];
	// automatically update changed files
	[prefs setObject:NSNumberFalse forKey:kWCPrefsFilesAutomaticallyUpdateChangedFilesKey];
	
	// animate adding and removing tabs
	[prefs setObject:NSNumberTrue forKey:kWCPrefsTabsAnimateAddingAndRemovingKey];
	// allow scrubbing of tabs
	[prefs setObject:NSNumberTrue forKey:kWCPrefsTabsAllowScrubbingOfTabsKey];
	// open new tabs in background
	[prefs setObject:NSNumberFalse forKey:kWCPrefsTabsOpenNewTabsInBackgroundKey];
	
	// add to project copy files
	[prefs setObject:NSNumberTrue forKey:kWCPrefsAddToProjectCopyFilesKey];
	// add to project default encoding type
	[prefs setObject:NSNumberWithUnsignedInteger(NoStringEncoding) forKey:kWCPrefsAddToProjectTextEncodingKey];
	// add to project open files after adding
	[prefs setObject:NSNumberFalse forKey:kWCPrefsAddToProjectOpenFilesAfterAddKey];
	
	// new file open after creation
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewFileOpenNewFileAfterCreationKey];
	
	// new target make new target active
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewTargetMakeNewTargetActiveKey];
	// new target copy active target's build steps to new target
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewTargetCopyActiveTargetsBuildStepsToNewTargetKey];
	
	// new configuration copy active configuration's defines to new configuration
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewConfigurationCopyActiveConfigurationsDefinesToNewConfigurationKey];
	// new configuration copy active configuration's include directories to new configuration
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewConfigurationCopyActiveConfigurationsIncludeDirectoriesToNewConfigurationKey];
	
	// new include directories recursively add subdirectories
	[prefs setObject:NSNumberTrue forKey:kWCPrefsNewIncludeDirectoryRecursivelyAddSubdirectoriesKey];
	
	// new project from folder root folder
	NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	[prefs setObject:[documentPaths lastObject] forKey:kWCNewProjectFromFolderRootFolderKey];
	// new project from folder selected target model
	[prefs setObject:NSNumberWithUnsignedInteger(WCBTModelTI83) forKey:kWCNewProjectFromFolderTargetModelKey];
	// new project from folder selected tartget output type
	[prefs setObject:NSNumberWithUnsignedInteger(WCBTOutputTypeProgram) forKey:kWCNewProjectFromFolderTargetOutputTypeKey];
	
	[[NSUserDefaults standardUserDefaults] registerDefaults:prefs];
}
#pragma mark *** Public Methods ***
+ (WCAppController *)sharedInstance; {
	static id _sharedInstance = nil;
	if (!_sharedInstance)
		_sharedInstance = [[[self class] alloc] init];
	return _sharedInstance;
}


#pragma mark Accessors

#pragma mark IBActions
- (IBAction)preferencesAction:(id)sender; {
	[[WCPreferencesWindowController sharedPrefsWindowController] showWindow:nil];
}
@end
